#include "../project/stdafx.h"
#include "FontHelper.h"

CFontHelper::CFontHelper() :
	m_Font(NULL),
	m_pData(NULL), m_nSize(0),
	m_nFontIndex(0), m_hFontRes(NULL)
{
	GdiplusStartupInput gdiplusStartupInput;
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
	m_pFontCollection = new PrivateFontCollection;
	m_pFontFamily = new Gdiplus::FontFamily;
}

CFontHelper::~CFontHelper()
{
	if (m_Font != NULL)
	{
		delete m_Font;
		m_Font = NULL;
	}

	if (m_pFontCollection != NULL)
	{
		delete m_pFontCollection;
		m_pFontCollection = NULL;
	}

	if (m_pFontFamily != NULL)
	{
		delete m_pFontFamily;
		m_pFontFamily = NULL;
	}

	if (m_hFontRes != NULL)
	{
		RemoveFontMemResourceEx(m_hFontRes);
		m_hFontRes = NULL;
	}

	if (!m_strFontFile.IsEmpty())
		RemoveFontResourceEx(m_strFontFile, FR_PRIVATE, NULL);

	GdiplusShutdown(gdiplusToken);
}

BOOL CFontHelper::LoadFont(UINT  lpszResource, LPCTSTR lpszType/* = _T("ttf")*/)
{
	HINSTANCE hInst = AfxGetResourceHandle();
	HRSRC hResrc = ::FindResource(hInst, MAKEINTRESOURCE(lpszResource), lpszType);
	if (hResrc == NULL)
		return FALSE;

	m_nSize = SizeofResource(hInst, hResrc);
	m_pData = LoadResource(hInst, hResrc);
	if (m_pData == NULL)
		return FALSE;

	// GDI
	m_nFontIndex = 0;
	m_hFontRes = AddFontMemResourceEx(
		m_pData,			// font resource
		m_nSize,			// number of bytes in font resource 
		NULL,				// Reserved. Must be 0.
		&m_nFontIndex);     // number of fonts installed
	if (m_hFontRes == NULL)
		return FALSE;

	// GDI+
	Gdiplus::Status nResults = m_pFontCollection->AddMemoryFont(m_pData, m_nSize);
	if (nResults != Gdiplus::Ok)
		return FALSE;

	int nNumFound = 0;
	m_pFontCollection->GetFamilies(1, m_pFontFamily, &nNumFound);
	if (nNumFound <= 0)
		return FALSE;

	return TRUE;
}

HFONT CFontHelper::FontToHFONTA(HWND hWnd)
{
	if (m_Font == NULL || hWnd == NULL)
		return NULL;

	int nNumFound = 0;
	m_pFontCollection->GetFamilies(1, m_pFontFamily, &nNumFound);
	if (nNumFound <= 0)
		return NULL;

	Graphics g(hWnd);
	LOGFONTA logFont;
	m_Font->GetLogFontA(&g, &logFont);
	logFont.lfQuality = CLEARTYPE_QUALITY;
	logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
	logFont.lfClipPrecision = CLIP_CHARACTER_PRECIS;
	logFont.lfCharSet = DEFAULT_CHARSET;
	logFont.lfPitchAndFamily = DEFAULT_PITCH;
	return ::CreateFontIndirectA(&logFont);
}

// GDI+ -> GDI
HFONT CFontHelper::FontToHFONTW(HWND hWnd)
{
	if (m_Font == NULL || hWnd == NULL)
		return NULL;

	Graphics g(hWnd);
	LOGFONTW logFont;

	m_Font->GetLogFontW(&g, &logFont);
	logFont.lfQuality = CLEARTYPE_QUALITY;
	logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
	logFont.lfClipPrecision = CLIP_CHARACTER_PRECIS;
	logFont.lfCharSet = DEFAULT_CHARSET;
	logFont.lfPitchAndFamily = DEFAULT_PITCH;
	return ::CreateFontIndirectW(&logFont);
}

// GDI+ -> GDI
HFONT CFontHelper::GetSafeHFONT(HWND hWnd)
{
#ifdef _UNICODE
	return FontToHFONTW(hWnd);
#else
	return FontToHFONTA(hWnd);
#endif // _UNICODE
}


// GDI+
Gdiplus::Font* CFontHelper::SetFontStyle(Gdiplus::FontStyle fontstyle/* = FontStyleRegular*/, REAL nFontSize/* = 14.0F*/)
{
	int nNumFound = 0;
	m_pFontCollection->GetFamilies(1, m_pFontFamily, &nNumFound);
	if (nNumFound <= 0)
		return NULL;

	if (m_Font != NULL)
	{
		delete m_Font;
		m_Font = NULL;
	}

	m_Font = new Gdiplus::Font(m_pFontFamily, nFontSize, fontstyle, UnitPixel);
	return m_Font;
}

// GDI
Gdiplus::FontFamily* CFontHelper::FontFamily()
{
	int nNumFound = 0;
	m_pFontCollection->GetFamilies(1, m_pFontFamily, &nNumFound);
	if (nNumFound <= 0)
		return NULL;

	return m_pFontFamily;
}

BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
{
	CFont* pFont = (CFont*)lParam;
	CWnd* pWnd = CWnd::FromHandle(hwndChild);
	pWnd->SetFont(pFont);
	return TRUE;
}

void CFontHelper::SetFont(HWND hWnd)
{
	CFont* pFont = CFont::FromHandle(GetSafeHFONT(hWnd));
	::EnumChildWindows(hWnd, EnumChildProc, (LPARAM)&pFont);
	::SendMessage(hWnd, WM_SETFONT, (WPARAM)GetSafeHFONT(hWnd), TRUE);
}
